package com.cheche.dn.domain.admin;

import com.cheche.dn.common.base.IdEntity;
import com.cheche.dn.domain.Apis;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Sets;

import javax.persistence.*;
import java.util.Set;

/**
 * Entity - Authority
 * Created by cheshun on 15/8/22.
 */
@Entity
@Table(name = "authority")
public class Authority extends IdEntity implements Apis {
    private static final long serialVersionUID = -486996966763435810L;

    public static final String NAME_PROPERTY_NAME = "name";

    public static final Authority SUPER_ADMIN = new Authority("/**", null, "超级管理员");

    public static final Authority ADMINS_POST = new Authority(ADMINS_POST_MAPPING, "创建管理员");
    public static final Authority ADMINS_SELF_GET = new Authority(ADMINS_SELF_GET_MAPPING, "获取当前管理员");
    public static final Authority ADMINS_ID_GET = new Authority(ADMINS_ID_GET_MAPPING, "获取管理员详情");
    public static final Authority ADMINS_GET = new Authority(ADMINS_GET_MAPPING, "获取管理员列表");
    public static final Authority ADMINS_PASSWORD_PATCH = new Authority(ADMINS_PASSWORD_PATCH_MAPPING, "管理员修改自己密码");
    public static final Authority ADMINS_ID_PASSWORD_PATCH = new Authority(ADMINS_ID_PASSWORD_PATCH_MAPPING, "重置指定管理员密码");
    public static final Authority ADMINS_ID_ROLES_POST = new Authority(ADMINS_ID_ROLES_POST_MAPPING, "添加管理员角色");
    public static final Authority ADMINS_ID_ROLES_DELETE = new Authority(ADMINS_ID_ROLES_DELETE_MAPPING, "删除管理员角色");
    public static final Authority AUTHORITIES_GET = new Authority(AUTHORITIES_GET_MAPPING, "获取全部权限列表");
    public static final Authority ROLES_POST = new Authority(ROLES_POST_MAPPING, "创建角色");
    public static final Authority ROLES_GET = new Authority(ROLES_GET_MAPPING, "获取角色列表");
    public static final Authority ROLES_PUT = new Authority(ROLES_PUT_MAPPING, "修改角色");
    public static final Authority ROLES_ID_AUTHORITIES_POST = new Authority(ROLES_ID_AUTHORITIES_POST_MAPPING, "添加角色权限");
    public static final Authority ROLES_ID_AUTHORITIES_DELETE = new Authority(ROLES_ID_AUTHORITIES_DELETE_MAPPING, "删除角色权限");
    public static final Authority ROLES_DELETE = new Authority(ROLES_DELETE_MAPPING, "删除多个角色");
    public static final Authority ROLES_ID_DELETE = new Authority(ROLES_ID_DELETE_MAPPING, "删除单个角色");
    public static final Authority ROLES_ID_GET = new Authority(ROLES_ID_GET_MAPPING, "获取角色详情");
    public static final Authority USERS_GET = new Authority(USERS_GET_MAPPING, "获取用户列表");
    public static final Authority USERS_POST = new Authority(USERS_POST_MAPPING, "添加用户");

    public static Set<Authority> values = Sets.newHashSet(
            ADMINS_POST, ADMINS_SELF_GET, ADMINS_ID_GET, ADMINS_GET, ADMINS_PASSWORD_PATCH, ADMINS_ID_PASSWORD_PATCH, ADMINS_ID_ROLES_POST, ADMINS_ID_ROLES_DELETE,
            AUTHORITIES_GET,
            ROLES_POST, ROLES_GET, ROLES_PUT, ROLES_ID_AUTHORITIES_POST, ROLES_ID_AUTHORITIES_DELETE, ROLES_DELETE, ROLES_ID_DELETE, ROLES_ID_GET,
            USERS_GET, USERS_POST
    );


    public Authority() {
    }

    public Authority(Mapping mapping, String description) {
        this.url = mapping.getUrl();
        this.method = mapping.getMethod().name();
        this.name = buildName(url, method);
        this.description = description;
    }

    public Authority(String url, String method, String description) {
        this.url = url;
        this.method = method;
        this.name = buildName(url, method);
        this.description = description;
    }

    private String buildName(String url, String method) {
        url = url.replace("/", "_").replace("{", "").replace("}", "");
        if (method == null || method.equals("")) {
            return String.format("ROLE_%s", url.toUpperCase());
        }
        return String.format("ROLE_%s_%s", url.toUpperCase(), method.toUpperCase());
    }

    private String url;             // 权限控制URL
    private String method;          // Http Method
    private String name;            // 权限名字
    private String description;     // 权限描述

    private Set<Role> roles = Sets.newHashSet();

    @JsonProperty
    @Column(length = 50, nullable = false)
    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @JsonProperty
    @Column(length = 10)
    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    @JsonProperty
    @Column(length = 50, nullable = false, unique = true)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @JsonProperty
    @Column(length = 100, nullable = false)
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @ManyToMany(mappedBy = "authorities", fetch = FetchType.LAZY)
    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    public static boolean contains(Authority auth) {
        return values.contains(auth);
    }
}
